from db import db
from datetime import datetime


class Model(db.Model):
    __abstract__ = True
    id = db.Column(db.Integer, primary_key=True)

    @classmethod
    def create(cls, commit=False, **kwargs):
        instance = cls(**kwargs)
        return instance.save(commit=commit)

    def save(self, commit=False):
        db.session.add(self)
        if commit:
            db.session.commit()
        return self

    def update(self, commit=False, **kwargs):
        for attr, value in kwargs.items():
            setattr(self, attr, value)
        return commit and self.save(commit=commit) or self

    def delete(self, commit=False):
        db.session.delete(self)
        if commit:
            db.session.commit()
        return self

    @classmethod
    def get(cls, _id):
        return cls.query.filter_by(id=_id, deleted=0).first()

    @classmethod
    def get_all(cls):
        return cls.query.filter_by(deleted=0).all()

    def to_dict(self, exclude_fields=None, only_fields=None):
        """
        同时传入 exclude_fields 和 only_fields 参数，并根据需要进行字段的过滤和选择。
        请注意，如果 exclude_fields 和 only_fields 中存在相同的字段名称，最终结果将优先考虑 only_fields，即该字段将被包含在输出字典中。
        """
        if only_fields is None:
            only_fields = []
        if exclude_fields is None:
            exclude_fields = []
        columns = self.__table__.columns

        if only_fields:
            result = {c.name: self._format_datetime(getattr(self, c.name, None)) for c in columns if
                      c.name in only_fields}
        elif exclude_fields:
            result = {c.name: self._format_datetime(getattr(self, c.name, None)) for c in columns if
                      c.name not in exclude_fields}
        else:
            result = {c.name: self._format_datetime(getattr(self, c.name, None)) for c in columns}

        if exclude_fields and only_fields:
            result = {k: v for k, v in result.items() if k not in exclude_fields or k in only_fields}

        return result

    def _format_datetime(self, value):
        if isinstance(value, datetime):
            return int(value.timestamp()) * 1000
        return value

class BaseMixins(db.Model):
    __abstract__ = True
    id = db.Column(db.Integer, primary_key=True)

    @classmethod
    def create(cls, commit=False, **kwargs):
        """Create a new record and save it the database."""
        instance = cls(**kwargs)
        return instance.save(commit=commit)

    def save(self, commit=False):
        db.session.add(self)
        if commit:
            db.session.commit()
        return self

    def update(self, commit=False, **kwargs):
        """Update specific fields of a record."""
        for attr, value in kwargs.items():
            setattr(self, attr, value)
        return commit and self.save(commit=commit) or self

    def delete(self, commit=False):
        db.session.delete(self)
        if commit:
            db.session.commit()
        return self

    @classmethod
    def get(cls, _id):
        return cls.query.filter_by(id=_id, deleted=0).first()

    @classmethod
    def get_all(cls):
        return cls.query.filter_by(deleted=0).all()

    def to_dict(self, exclude_fields=None, only_fields=None):
        """
        同时传入 exclude_fields 和 only_fields 参数，并根据需要进行字段的过滤和选择。
        请注意，如果 exclude_fields 和 only_fields 中存在相同的字段名称，最终结果将优先考虑 only_fields，即该字段将被包含在输出字典中。
        """
        if only_fields is None:
            only_fields = []
        if exclude_fields is None:
            exclude_fields = []
        columns = self.__table__.columns

        if only_fields:
            result = {c.name: self._format_datetime(getattr(self, c.name, None)) for c in columns if c.name in only_fields}
        elif exclude_fields:
            result = {c.name: self._format_datetime(getattr(self, c.name, None)) for c in columns if c.name not in exclude_fields}
        else:
            result = {c.name: self._format_datetime(getattr(self, c.name, None)) for c in columns}

        if exclude_fields and only_fields:
            result = {k: v for k, v in result.items() if k not in exclude_fields or k in only_fields}

        return result

    def _format_datetime(self, value):
        """将datetime类型字段转换为时间戳"""
        if isinstance(value, datetime):
            return int(value.timestamp()) * 1000
        return value